package de.jonasjelten.jcalc.api;

import de.jonasjelten.jcalc.exception.JCalcException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Socketverbindung für jCalc -> noch einfacher für PHP & co, even telnet possible
 * @author Jonas
 */
public class JCalcSocket extends Thread implements JCalcInterface {

    int handlertyp;
    Socket client;
    PrintStream out;
    BufferedReader in;

    public JCalcSocket(int typ, Socket clientconnection) {
        super("JCalcSocket");
        if (typ == 0) { // Listener
            handlertyp = 0;
            int port = 888;
            e("Server launching on port " + port);
            ServerSocket ss;
            try {
                ss = new ServerSocket(port);
                e("kk launched");
                Socket cl = ss.accept();
                e("connection recieved");
                JCalcSocket ie = new JCalcSocket(1, cl);
                e("handler started");
                ie.start();
            } catch (IOException ex) {
                if(out != null ) out.println("ERROR:");
                e(ex.toString());
                System.out.println("ERROR:");
                ex.printStackTrace(System.out);
                if(out != null ) ex.printStackTrace(out);
            }
        } else if (typ == 1) { // Handler
            handlertyp = 1;
            client = clientconnection;
        }
    }

    public JCalcSocket() {
        this(0, null);
    }

    public static void main(String[] arg) {
        JCalcSocket iee = new JCalcSocket();
    }

    public final void e(String txt) {
        System.out.println(txt);
    }

    @Override
    public void run() {
        try {
            e("thread launched");
            in = new BufferedReader(new InputStreamReader(client.getInputStream()));
            out = new PrintStream(client.getOutputStream());
            out.flush();
            eo("jCalc Server ready");
            eo("waitin 4 input");
            JCalc mycalc = new JCalc(this);
            boolean closed = false;
            while (!closed) {
                String line = in.readLine();
                if (line == null) {
                    closed = true;
                } else {
                    // DO what with line
                    e("Line read: " +line);
                    eo("");
                    try {
                        mycalc.evalMathExp(mycalc.parse(line));
                    } catch (JCalcException e) {
                        eo("JException: " + e.toString() + " msg: "+ e.getLocalizedMessage());
                        System.err.print("JException: "+e);
                    } catch (Exception e) {
                        System.err.print(e);
                    }
                }
            }

        } catch (IOException ex) {
            eo("ERROR:");
            e(ex.toString());
            System.out.println("ERROR:");
            ex.printStackTrace(System.out);
            ex.printStackTrace(out);
        }
    }

    @Override
    public void finishedCalculating(String message) {
        
    }

    @Override
    public void intermediateResult(String message) {
        e(message);
    }

    @Override
    public void echo(String txt) {
        e(txt);
    }

    @Override
    public void setProgress(int progress) {
        
    }

    @Override
    public void finalResult(String result) {
        out.println();
        out.println(result);
        e(result);
    }
    
    @Override
    public void errorMessage(String message) {
        eo("ErrMsg: " + message);
    }

    public void eo(String txt) {
        out.println(txt);
    }
}
